## Makefile.am for gtk+/demos
include $(top_srcdir)/Makefile.decl
-SUBDIRS = gtk-demo
-
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_builddir)/gdk \
- -DGDK_DISABLE_DEPRECATED \
- -DGTK_DISABLE_DEPRECATED \
- $(GTK_DEBUG_FLAGS) \
- $(GTK_DEP_CFLAGS)
-
-DEPS = \
- $(top_builddir)/gtk/libgtk-3.la
-
-LDADDS = \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(MATH_LIB)
-
-noinst_PROGRAMS = \
- testanimation \
- testpixbuf-color \
- testpixbuf-save \
- testpixbuf-scale \
- pixbuf-demo
-
-testpixbuf_save_DEPENDENCIES = $(DEPS)
-testpixbuf_color_DEPENDENCIES = $(DEPS)
-testpixbuf_scale_DEPENDENCIES = $(DEPS)
-testanimation_DEPENDENCIES = $(DEPS)
-pixbuf_demo_DEPENDENCIES = $(DEPS)
-
-testpixbuf_save_LDADD = $(LDADDS)
-testpixbuf_color_LDADD = $(LDADDS)
-testpixbuf_scale_LDADD = $(LDADDS)
-testanimation_LDADD = $(LDADDS)
-pixbuf_demo_LDADD = $(LDADDS)
-
-testpixbuf_save_SOURCES = testpixbuf-save.c
-testpixbuf_color_SOURCES = testpixbuf-color.c
-testpixbuf_scale_SOURCES = testpixbuf-scale.c
-testanimation_SOURCES = testanimation.c
-pixbuf_demo_SOURCES = pixbuf-demo.c
-
-EXTRA_DIST += \
- apple-red.png \
- background.jpg \
- gnome-applets.png \
- gnome-calendar.png \
- gnome-foot.png \
- gnome-gimp.png \
- gnome-gmush.png \
- gnome-gsame.png \
- gnu-keys.png
+SUBDIRS = gtk-demo pixbuf-demo
-include $(top_srcdir)/git.mk
+++ /dev/null
-/* GdkPixbuf library - Scaling and compositing demo
- *
- * Copyright (C) 1999 The Free Software Foundation
- *
- * Authors: Federico Mena-Quintero <federico@gimp.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-#include <stdlib.h>
-#include <gtk/gtk.h>
-#include <math.h>
-
-\f
-
-#define FRAME_DELAY 50
-
-#define BACKGROUND_NAME "background.jpg"
-
-static const char *image_names[] = {
- "apple-red.png",
- "gnome-applets.png",
- "gnome-calendar.png",
- "gnome-foot.png",
- "gnome-gmush.png",
- "gnome-gimp.png",
- "gnome-gsame.png",
- "gnu-keys.png"
-};
-
-#define N_IMAGES (sizeof (image_names) / sizeof (image_names[0]))
-
-/* Current frame */
-static GdkPixbuf *frame;
-
-/* Background image */
-static GdkPixbuf *background;
-static int back_width, back_height;
-
-/* Images */
-static GdkPixbuf *images[N_IMAGES];
-
-/* Widgets */
-static GtkWidget *da;
-
-\f
-
-/* Loads the images for the demo and returns whether the operation succeeded */
-static gboolean
-load_pixbufs (void)
-{
- int i;
-
- /* We pass NULL for the error return location, we don't care
- * about the error message.
- */
-
- background = gdk_pixbuf_new_from_file (BACKGROUND_NAME, NULL);
- if (!background)
- return FALSE;
-
- back_width = gdk_pixbuf_get_width (background);
- back_height = gdk_pixbuf_get_height (background);
-
- for (i = 0; i < N_IMAGES; i++) {
- images[i] = gdk_pixbuf_new_from_file (image_names[i], NULL);
- if (!images[i])
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Expose callback for the drawing area */
-static gboolean
-draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
-{
- gdk_cairo_set_source_pixbuf (cr, frame, 0, 0);
- cairo_paint (cr);
-
- return TRUE;
-}
-
-#define CYCLE_LEN 60
-
-static int frame_num;
-
-/* Timeout handler to regenerate the frame */
-static gint
-timeout (gpointer data)
-{
- double f;
- int i;
- double xmid, ymid;
- double radius;
-
- gdk_pixbuf_copy_area (background, 0, 0, back_width, back_height,
- frame, 0, 0);
-
- f = (double) (frame_num % CYCLE_LEN) / CYCLE_LEN;
-
- xmid = back_width / 2.0;
- ymid = back_height / 2.0;
-
- radius = MIN (xmid, ymid) / 2.0;
-
- for (i = 0; i < N_IMAGES; i++) {
- double ang;
- int xpos, ypos;
- int iw, ih;
- double r;
- GdkRectangle r1, r2, dest;
- double k;
-
- ang = 2.0 * G_PI * (double) i / N_IMAGES - f * 2.0 * G_PI;
-
- iw = gdk_pixbuf_get_width (images[i]);
- ih = gdk_pixbuf_get_height (images[i]);
-
- r = radius + (radius / 3.0) * sin (f * 2.0 * G_PI);
-
- xpos = floor (xmid + r * cos (ang) - iw / 2.0 + 0.5);
- ypos = floor (ymid + r * sin (ang) - ih / 2.0 + 0.5);
-
- k = (i & 1) ? sin (f * 2.0 * G_PI) : cos (f * 2.0 * G_PI);
- k = 2.0 * k * k;
- k = MAX (0.25, k);
-
- r1.x = xpos;
- r1.y = ypos;
- r1.width = iw * k;
- r1.height = ih * k;
-
- r2.x = 0;
- r2.y = 0;
- r2.width = back_width;
- r2.height = back_height;
-
- if (gdk_rectangle_intersect (&r1, &r2, &dest))
- gdk_pixbuf_composite (images[i],
- frame,
- dest.x, dest.y,
- dest.width, dest.height,
- xpos, ypos,
- k, k,
- GDK_INTERP_NEAREST,
- ((i & 1)
- ? MAX (127, fabs (255 * sin (f * 2.0 * G_PI)))
- : MAX (127, fabs (255 * cos (f * 2.0 * G_PI)))));
- }
-
- gtk_widget_queue_draw (da);
-
- frame_num++;
- return TRUE;
-}
-
-static guint timeout_id;
-
-/* Destroy handler for the window */
-static void
-destroy_cb (GObject *object, gpointer data)
-{
- g_source_remove (timeout_id);
- timeout_id = 0;
-
- gtk_main_quit ();
-}
-
-int
-main (int argc, char **argv)
-{
- GtkWidget *window;
-
- gtk_init (&argc, &argv);
-
- if (!load_pixbufs ()) {
- g_message ("main(): Could not load all the pixbufs!");
- exit (EXIT_FAILURE);
- }
-
- frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, back_width, back_height);
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
- gtk_widget_set_size_request (window, back_width, back_height);
- gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
-
- g_signal_connect (window, "destroy",
- G_CALLBACK (destroy_cb), NULL);
-
- da = gtk_drawing_area_new ();
-
- g_signal_connect (da, "draw",
- G_CALLBACK (draw_cb), NULL);
-
- gtk_container_add (GTK_CONTAINER (window), da);
-
- timeout_id = gdk_threads_add_timeout (FRAME_DELAY, timeout, NULL);
-
- gtk_widget_show_all (window);
- gtk_main ();
-
- return 0;
-}
--- /dev/null
+## Makefile.am for gtk+/demos
+include $(top_srcdir)/Makefile.decl
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_builddir)/gdk \
+ -DGDK_DISABLE_DEPRECATED \
+ -DGTK_DISABLE_DEPRECATED \
+ $(GTK_DEBUG_FLAGS) \
+ $(GTK_DEP_CFLAGS)
+
+DEPS = \
+ $(top_builddir)/gtk/libgtk-3.la
+
+LDADDS = \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(MATH_LIB)
+
+noinst_PROGRAMS = \
+ pixbuf-demo
+
+pixbuf_demo_DEPENDENCIES = $(DEPS)
+
+pixbuf_demo_LDADD = $(LDADDS)
+
+pixbuf_demo_SOURCES = pixbuf-demo.c
+
+EXTRA_DIST += \
+ apple-red.png \
+ background.jpg \
+ gnome-applets.png \
+ gnome-calendar.png \
+ gnome-foot.png \
+ gnome-gimp.png \
+ gnome-gmush.png \
+ gnome-gsame.png \
+ gnu-keys.png
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+/* GdkPixbuf library - Scaling and compositing demo
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Federico Mena-Quintero <federico@gimp.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <math.h>
+
+\f
+
+#define FRAME_DELAY 50
+
+#define BACKGROUND_NAME "background.jpg"
+
+static const char *image_names[] = {
+ "apple-red.png",
+ "gnome-applets.png",
+ "gnome-calendar.png",
+ "gnome-foot.png",
+ "gnome-gmush.png",
+ "gnome-gimp.png",
+ "gnome-gsame.png",
+ "gnu-keys.png"
+};
+
+#define N_IMAGES (sizeof (image_names) / sizeof (image_names[0]))
+
+/* Current frame */
+static GdkPixbuf *frame;
+
+/* Background image */
+static GdkPixbuf *background;
+static int back_width, back_height;
+
+/* Images */
+static GdkPixbuf *images[N_IMAGES];
+
+/* Widgets */
+static GtkWidget *da;
+
+\f
+
+/* Loads the images for the demo and returns whether the operation succeeded */
+static gboolean
+load_pixbufs (void)
+{
+ int i;
+
+ /* We pass NULL for the error return location, we don't care
+ * about the error message.
+ */
+
+ background = gdk_pixbuf_new_from_file (BACKGROUND_NAME, NULL);
+ if (!background)
+ return FALSE;
+
+ back_width = gdk_pixbuf_get_width (background);
+ back_height = gdk_pixbuf_get_height (background);
+
+ for (i = 0; i < N_IMAGES; i++) {
+ images[i] = gdk_pixbuf_new_from_file (image_names[i], NULL);
+ if (!images[i])
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Expose callback for the drawing area */
+static gboolean
+draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+ gdk_cairo_set_source_pixbuf (cr, frame, 0, 0);
+ cairo_paint (cr);
+
+ return TRUE;
+}
+
+#define CYCLE_LEN 60
+
+static int frame_num;
+
+/* Timeout handler to regenerate the frame */
+static gint
+timeout (gpointer data)
+{
+ double f;
+ int i;
+ double xmid, ymid;
+ double radius;
+
+ gdk_pixbuf_copy_area (background, 0, 0, back_width, back_height,
+ frame, 0, 0);
+
+ f = (double) (frame_num % CYCLE_LEN) / CYCLE_LEN;
+
+ xmid = back_width / 2.0;
+ ymid = back_height / 2.0;
+
+ radius = MIN (xmid, ymid) / 2.0;
+
+ for (i = 0; i < N_IMAGES; i++) {
+ double ang;
+ int xpos, ypos;
+ int iw, ih;
+ double r;
+ GdkRectangle r1, r2, dest;
+ double k;
+
+ ang = 2.0 * G_PI * (double) i / N_IMAGES - f * 2.0 * G_PI;
+
+ iw = gdk_pixbuf_get_width (images[i]);
+ ih = gdk_pixbuf_get_height (images[i]);
+
+ r = radius + (radius / 3.0) * sin (f * 2.0 * G_PI);
+
+ xpos = floor (xmid + r * cos (ang) - iw / 2.0 + 0.5);
+ ypos = floor (ymid + r * sin (ang) - ih / 2.0 + 0.5);
+
+ k = (i & 1) ? sin (f * 2.0 * G_PI) : cos (f * 2.0 * G_PI);
+ k = 2.0 * k * k;
+ k = MAX (0.25, k);
+
+ r1.x = xpos;
+ r1.y = ypos;
+ r1.width = iw * k;
+ r1.height = ih * k;
+
+ r2.x = 0;
+ r2.y = 0;
+ r2.width = back_width;
+ r2.height = back_height;
+
+ if (gdk_rectangle_intersect (&r1, &r2, &dest))
+ gdk_pixbuf_composite (images[i],
+ frame,
+ dest.x, dest.y,
+ dest.width, dest.height,
+ xpos, ypos,
+ k, k,
+ GDK_INTERP_NEAREST,
+ ((i & 1)
+ ? MAX (127, fabs (255 * sin (f * 2.0 * G_PI)))
+ : MAX (127, fabs (255 * cos (f * 2.0 * G_PI)))));
+ }
+
+ gtk_widget_queue_draw (da);
+
+ frame_num++;
+ return TRUE;
+}
+
+static guint timeout_id;
+
+/* Destroy handler for the window */
+static void
+destroy_cb (GObject *object, gpointer data)
+{
+ g_source_remove (timeout_id);
+ timeout_id = 0;
+
+ gtk_main_quit ();
+}
+
+int
+main (int argc, char **argv)
+{
+ GtkWidget *window;
+
+ gtk_init (&argc, &argv);
+
+ if (!load_pixbufs ()) {
+ g_message ("main(): Could not load all the pixbufs!");
+ exit (EXIT_FAILURE);
+ }
+
+ frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, back_width, back_height);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ gtk_widget_set_size_request (window, back_width, back_height);
+ gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
+
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (destroy_cb), NULL);
+
+ da = gtk_drawing_area_new ();
+
+ g_signal_connect (da, "draw",
+ G_CALLBACK (draw_cb), NULL);
+
+ gtk_container_add (GTK_CONTAINER (window), da);
+
+ timeout_id = gdk_threads_add_timeout (FRAME_DELAY, timeout, NULL);
+
+ gtk_widget_show_all (window);
+ gtk_main ();
+
+ return 0;
+}
+++ /dev/null
-
-/* testpixbuf -- test program for gdk-pixbuf code
- * Copyright (C) 1999 Mark Crichton, Larry Ewing
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <gtk/gtk.h>
-
-typedef struct _LoadContext LoadContext;
-
-struct _LoadContext
-{
- gchar *filename;
- GtkWidget *window;
- GdkPixbufLoader *pixbuf_loader;
- guint load_timeout;
- FILE* image_stream;
-};
-
-static void
-destroy_context (gpointer data)
-{
- LoadContext *lc = data;
-
- g_free (lc->filename);
-
- if (lc->load_timeout)
- g_source_remove (lc->load_timeout);
-
- if (lc->image_stream)
- fclose (lc->image_stream);
-
- if (lc->pixbuf_loader)
- {
- gdk_pixbuf_loader_close (lc->pixbuf_loader, NULL);
- g_object_unref (lc->pixbuf_loader);
- }
-
- g_free (lc);
-}
-
-static LoadContext*
-get_load_context (GtkWidget *image)
-{
- LoadContext *lc;
-
- lc = g_object_get_data (G_OBJECT (image), "lc");
-
- if (lc == NULL)
- {
- lc = g_new0 (LoadContext, 1);
-
- g_object_set_data_full (G_OBJECT (image),
- "lc",
- lc,
- destroy_context);
- }
-
- return lc;
-}
-
-static void
-progressive_prepared_callback (GdkPixbufLoader* loader,
- gpointer data)
-{
- GdkPixbuf* pixbuf;
- GtkWidget* image;
-
- image = GTK_WIDGET (data);
-
- pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
-
- /* Avoid displaying random memory contents, since the pixbuf
- * isn't filled in yet.
- */
- gdk_pixbuf_fill (pixbuf, 0xaaaaaaff);
-
- /* Could set the pixbuf instead, if we only wanted to display
- * static images.
- */
- gtk_image_set_from_animation (GTK_IMAGE (image),
- gdk_pixbuf_loader_get_animation (loader));
-}
-
-static void
-progressive_updated_callback (GdkPixbufLoader* loader,
- gint x, gint y, gint width, gint height,
- gpointer data)
-{
- GtkWidget* image;
-
- image = GTK_WIDGET (data);
-
- /* We know the pixbuf inside the GtkImage has changed, but the image
- * itself doesn't know this; so queue a redraw. If we wanted to be
- * really efficient, we could use a drawing area or something
- * instead of a GtkImage, so we could control the exact position of
- * the pixbuf on the display, then we could queue a draw for only
- * the updated area of the image.
- */
-
- /* We only really need to redraw if the image's animation iterator
- * is gdk_pixbuf_animation_iter_on_currently_loading_frame(), but
- * who cares.
- */
-
- gtk_widget_queue_draw (image);
-}
-
-static gint
-progressive_timeout (gpointer data)
-{
- GtkWidget *image;
- LoadContext *lc;
-
- image = GTK_WIDGET (data);
- lc = get_load_context (image);
-
- /* This shows off fully-paranoid error handling, so looks scary.
- * You could factor out the error handling code into a nice separate
- * function to make things nicer.
- */
-
- if (lc->image_stream)
- {
- size_t bytes_read;
- guchar buf[256];
- GError *error = NULL;
-
- bytes_read = fread (buf, 1, 256, lc->image_stream);
-
- if (ferror (lc->image_stream))
- {
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Failure reading image file 'alphatest.png': %s",
- g_strerror (errno));
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (gtk_widget_destroy), NULL);
-
- fclose (lc->image_stream);
- lc->image_stream = NULL;
-
- gtk_widget_show (dialog);
-
- lc->load_timeout = 0;
-
- return FALSE; /* uninstall the timeout */
- }
-
- if (!gdk_pixbuf_loader_write (lc->pixbuf_loader,
- buf, bytes_read,
- &error))
- {
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Failed to load image: %s",
- error->message);
-
- g_error_free (error);
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (gtk_widget_destroy), NULL);
-
- fclose (lc->image_stream);
- lc->image_stream = NULL;
-
- gtk_widget_show (dialog);
-
- lc->load_timeout = 0;
-
- return FALSE; /* uninstall the timeout */
- }
-
- if (feof (lc->image_stream))
- {
- fclose (lc->image_stream);
- lc->image_stream = NULL;
-
- /* Errors can happen on close, e.g. if the image
- * file was truncated we'll know on close that
- * it was incomplete.
- */
- error = NULL;
- if (!gdk_pixbuf_loader_close (lc->pixbuf_loader,
- &error))
- {
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Failed to load image: %s",
- error->message);
-
- g_error_free (error);
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (gtk_widget_destroy), NULL);
-
- gtk_widget_show (dialog);
-
- g_object_unref (lc->pixbuf_loader);
- lc->pixbuf_loader = NULL;
-
- lc->load_timeout = 0;
-
- return FALSE; /* uninstall the timeout */
- }
-
- g_object_unref (lc->pixbuf_loader);
- lc->pixbuf_loader = NULL;
- }
- }
- else
- {
- lc->image_stream = fopen (lc->filename, "r");
-
- if (lc->image_stream == NULL)
- {
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Unable to open image file '%s': %s",
- lc->filename,
- g_strerror (errno));
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (gtk_widget_destroy), NULL);
-
- gtk_widget_show (dialog);
-
- lc->load_timeout = 0;
-
- return FALSE; /* uninstall the timeout */
- }
-
- if (lc->pixbuf_loader)
- {
- gdk_pixbuf_loader_close (lc->pixbuf_loader, NULL);
- g_object_unref (lc->pixbuf_loader);
- lc->pixbuf_loader = NULL;
- }
-
- lc->pixbuf_loader = gdk_pixbuf_loader_new ();
-
- g_signal_connect (lc->pixbuf_loader, "area_prepared",
- G_CALLBACK (progressive_prepared_callback), image);
- g_signal_connect (lc->pixbuf_loader, "area_updated",
- G_CALLBACK (progressive_updated_callback), image);
- }
-
- /* leave timeout installed */
- return TRUE;
-}
-
-static void
-start_progressive_loading (GtkWidget *image)
-{
- LoadContext *lc;
-
- lc = get_load_context (image);
-
- /* This is obviously totally contrived (we slow down loading
- * on purpose to show how incremental loading works).
- * The real purpose of incremental loading is the case where
- * you are reading data from a slow source such as the network.
- * The timeout simply simulates a slow data source by inserting
- * pauses in the reading process.
- */
- lc->load_timeout = gdk_threads_add_timeout (100,
- progressive_timeout,
- image);
-}
-
-static GtkWidget *
-do_image (const char *filename)
-{
- GtkWidget *frame;
- GtkWidget *vbox;
- GtkWidget *image;
- GtkWidget *label;
- GtkWidget *align;
- GtkWidget *window;
- gchar *str, *escaped;
- LoadContext *lc;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW (window), "Image Loading");
-
- gtk_container_set_border_width (GTK_CONTAINER (window), 8);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- label = gtk_label_new (NULL);
- gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
- escaped = g_markup_escape_text (filename, -1);
- str = g_strdup_printf ("Progressively loading: <b>%s</b>", escaped);
- gtk_label_set_markup (GTK_LABEL (label),
- str);
- g_free (escaped);
- g_free (str);
-
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
- /* The alignment keeps the frame from growing when users resize
- * the window
- */
- align = gtk_alignment_new (0.5, 0.5, 0, 0);
- gtk_container_add (GTK_CONTAINER (align), frame);
- gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
-
- image = gtk_image_new_from_pixbuf (NULL);
- gtk_container_add (GTK_CONTAINER (frame), image);
-
- lc = get_load_context (image);
-
- lc->window = window;
- lc->filename = g_strdup (filename);
-
- start_progressive_loading (image);
-
- g_signal_connect (window, "destroy",
- G_CALLBACK (gtk_main_quit), NULL);
-
- g_signal_connect (window, "delete_event",
- G_CALLBACK (gtk_main_quit), NULL);
-
- gtk_widget_show_all (window);
-
- return window;
-}
-
-static void
-do_nonprogressive (const gchar *filename)
-{
- GtkWidget *frame;
- GtkWidget *vbox;
- GtkWidget *image;
- GtkWidget *label;
- GtkWidget *align;
- GtkWidget *window;
- gchar *str, *escaped;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW (window), "Animation");
-
- gtk_container_set_border_width (GTK_CONTAINER (window), 8);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- label = gtk_label_new (NULL);
- gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
- escaped = g_markup_escape_text (filename, -1);
- str = g_strdup_printf ("Loaded from file: <b>%s</b>", escaped);
- gtk_label_set_markup (GTK_LABEL (label),
- str);
- g_free (escaped);
- g_free (str);
-
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
- /* The alignment keeps the frame from growing when users resize
- * the window
- */
- align = gtk_alignment_new (0.5, 0.5, 0, 0);
- gtk_container_add (GTK_CONTAINER (align), frame);
- gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
-
- image = gtk_image_new_from_file (filename);
- gtk_container_add (GTK_CONTAINER (frame), image);
-
- g_signal_connect (window, "destroy",
- G_CALLBACK (gtk_main_quit), NULL);
-
- g_signal_connect (window, "delete_event",
- G_CALLBACK (gtk_main_quit), NULL);
-
- gtk_widget_show_all (window);
-}
-
-int
-main (int argc,
- char **argv)
-{
- gint i;
-
- gtk_init (&argc, &argv);
-
- i = 1;
- while (i < argc)
- {
- do_image (argv[i]);
- do_nonprogressive (argv[i]);
-
- ++i;
- }
-
- gtk_main ();
-
- return 0;
-}
-
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-#define ICC_PROFILE "/usr/share/color/icc/bluish.icc"
-#define ICC_PROFILE_SIZE 3966
-
-static gboolean
-save_image_png (const gchar *filename, GdkPixbuf *pixbuf, GError **error)
-{
- gchar *contents = NULL;
- gchar *contents_encode = NULL;
- gsize length;
- gboolean ret;
- gint len;
-
- /* get icc file */
- ret = g_file_get_contents (ICC_PROFILE, &contents, &length, error);
- if (!ret)
- goto out;
- contents_encode = g_base64_encode ((const guchar *) contents, length);
- ret = gdk_pixbuf_save (pixbuf, filename, "png", error,
- "tEXt::Software", "Hello my name is dave",
- "icc-profile", contents_encode,
- NULL);
- len = strlen (contents_encode);
- g_debug ("ICC profile was %i bytes", len);
-out:
- g_free (contents);
- g_free (contents_encode);
- return ret;
-}
-
-static gboolean
-save_image_tiff (const gchar *filename, GdkPixbuf *pixbuf, GError **error)
-{
- gchar *contents = NULL;
- gchar *contents_encode = NULL;
- gsize length;
- gboolean ret;
- gint len;
-
- /* get icc file */
- ret = g_file_get_contents (ICC_PROFILE, &contents, &length, error);
- if (!ret)
- goto out;
- contents_encode = g_base64_encode ((const guchar *) contents, length);
- ret = gdk_pixbuf_save (pixbuf, filename, "tiff", error,
- "icc-profile", contents_encode,
- NULL);
- len = strlen (contents_encode);
- g_debug ("ICC profile was %i bytes", len);
-out:
- g_free (contents);
- g_free (contents_encode);
- return ret;
-}
-
-static gboolean
-save_image_verify (const gchar *filename, GError **error)
-{
- gboolean ret = FALSE;
- GdkPixbuf *pixbuf = NULL;
- const gchar *option;
- gchar *icc_profile = NULL;
- gsize len = 0;
-
- /* load */
- pixbuf = gdk_pixbuf_new_from_file (filename, error);
- if (pixbuf == NULL)
- goto out;
-
- /* check values */
- option = gdk_pixbuf_get_option (pixbuf, "icc-profile");
- if (option == NULL) {
- *error = g_error_new (1, 0, "no profile set");
- goto out;
- }
-
- /* decode base64 */
- icc_profile = (gchar *) g_base64_decode (option, &len);
- if (len != ICC_PROFILE_SIZE) {
- *error = g_error_new (1, 0,
- "profile length invalid, got %" G_GSIZE_FORMAT,
- len);
- g_file_set_contents ("error.icc", icc_profile, len, NULL);
- goto out;
- }
-
- /* success */
- ret = TRUE;
-out:
- if (pixbuf != NULL)
- g_object_unref (pixbuf);
- g_free (icc_profile);
- return ret;
-}
-
-int
-main (int argc, char **argv)
-{
- GdkWindow *root;
- GdkPixbuf *pixbuf;
- gboolean ret;
- gint retval = 1;
- GError *error = NULL;
-
- gtk_init (&argc, &argv);
-
- root = gdk_get_default_root_window ();
- pixbuf = gdk_pixbuf_get_from_window (root,
- 0, 0, 150, 160);
-
- /* PASS */
- g_debug ("try to save PNG with a profile");
- ret = save_image_png ("icc-profile.png", pixbuf, &error);
- if (!ret) {
- g_warning ("FAILED: did not save image: %s", error->message);
- g_error_free (error);
- goto out;
- }
-
- /* PASS */
- g_debug ("try to save TIFF with a profile");
- ret = save_image_tiff ("icc-profile.tiff", pixbuf, &error);
- if (!ret) {
- g_warning ("FAILED: did not save image: %s", error->message);
- g_error_free (error);
- goto out;
- }
-
- /* PASS */
- g_debug ("try to load PNG and get color attributes");
- ret = save_image_verify ("icc-profile.png", &error);
- if (!ret) {
- g_warning ("FAILED: did not load image: %s", error->message);
- g_error_free (error);
- goto out;
- }
-
- /* PASS */
- g_debug ("try to load TIFF and get color attributes");
- ret = save_image_verify ("icc-profile.tiff", &error);
- if (!ret) {
- g_warning ("FAILED: did not load image: %s", error->message);
- g_error_free (error);
- goto out;
- }
-
- /* success */
- retval = 0;
- g_debug ("ALL OKAY!");
-out:
- return retval;
-}
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-
-#include "config.h"
-#include <stdio.h>
-
-#include <gtk/gtk.h>
-
-static void
-compare_pixbufs (GdkPixbuf *pixbuf, GdkPixbuf *compare, const gchar *file_type)
-{
- if ((gdk_pixbuf_get_width (pixbuf) !=
- gdk_pixbuf_get_width (compare)) ||
- (gdk_pixbuf_get_height (pixbuf) !=
- gdk_pixbuf_get_height (compare)) ||
- (gdk_pixbuf_get_n_channels (pixbuf) !=
- gdk_pixbuf_get_n_channels (compare)) ||
- (gdk_pixbuf_get_has_alpha (pixbuf) !=
- gdk_pixbuf_get_has_alpha (compare)) ||
- (gdk_pixbuf_get_bits_per_sample (pixbuf) !=
- gdk_pixbuf_get_bits_per_sample (compare))) {
- fprintf (stderr,
- "saved %s file differs from copy in memory\n",
- file_type);
- } else {
- guchar *orig_pixels;
- guchar *compare_pixels;
- gint orig_rowstride;
- gint compare_rowstride;
- gint width;
- gint height;
- gint bytes_per_pixel;
- gint x, y;
- guchar *p1, *p2;
- gint count = 0;
-
- orig_pixels = gdk_pixbuf_get_pixels (pixbuf);
- compare_pixels = gdk_pixbuf_get_pixels (compare);
-
- orig_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- compare_rowstride = gdk_pixbuf_get_rowstride (compare);
-
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
-
- /* well... */
- bytes_per_pixel = gdk_pixbuf_get_n_channels (pixbuf);
-
- p1 = orig_pixels;
- p2 = compare_pixels;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width * bytes_per_pixel; x++)
- count += (*p1++ != *p2++);
-
- orig_pixels += orig_rowstride;
- compare_pixels += compare_rowstride;
-
- p1 = orig_pixels;
- p2 = compare_pixels;
- }
-
- if (count > 0) {
- fprintf (stderr,
- "saved %s file differs from copy in memory\n",
- file_type);
- }
- }
-}
-
-static gboolean
-save_to_loader (const gchar *buf, gsize count, GError **err, gpointer data)
-{
- GdkPixbufLoader *loader = data;
-
- return gdk_pixbuf_loader_write (loader, (const guchar *)buf, count, err);
-}
-
-static GdkPixbuf *
-buffer_to_pixbuf (const gchar *buf, gsize count, GError **err)
-{
- GdkPixbufLoader *loader;
- GdkPixbuf *pixbuf;
-
- loader = gdk_pixbuf_loader_new ();
- if (gdk_pixbuf_loader_write (loader, (const guchar *)buf, count, err) &&
- gdk_pixbuf_loader_close (loader, err)) {
- pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
- g_object_unref (loader);
- return pixbuf;
- } else {
- return NULL;
- }
-}
-
-static void
-do_compare (GdkPixbuf *pixbuf, GdkPixbuf *compare, GError *err)
-{
- if (compare == NULL) {
- fprintf (stderr, "%s", err->message);
- g_error_free (err);
- } else {
- compare_pixbufs (pixbuf, compare, "jpeg");
- g_object_unref (compare);
- }
-}
-
-static void
-keypress_check (GtkWidget *widget, GdkEventKey *evt, gpointer data)
-{
- GdkPixbuf *pixbuf;
- GtkDrawingArea *da = (GtkDrawingArea*)data;
- GError *err = NULL;
- gchar *buffer;
- gsize count;
- GdkPixbufLoader *loader;
-
- pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (da), "pixbuf");
-
- if (evt->keyval == 'q')
- gtk_main_quit ();
-
- if (evt->keyval == 's' && (evt->state & GDK_CONTROL_MASK)) {
- /* save to callback */
- if (pixbuf == NULL) {
- fprintf (stderr, "PIXBUF NULL\n");
- return;
- }
-
- loader = gdk_pixbuf_loader_new ();
- if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "jpeg",
- &err,
- "quality", "100",
- NULL) ||
- !gdk_pixbuf_loader_close (loader, &err)) {
- fprintf (stderr, "%s", err->message);
- g_error_free (err);
- } else {
- do_compare (pixbuf,
- g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
- err);
- g_object_unref (loader);
- }
- }
- else if (evt->keyval == 'S') {
- /* save to buffer */
- if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "jpeg",
- &err,
- "quality", "100",
- NULL)) {
- fprintf (stderr, "%s", err->message);
- g_error_free (err);
- } else {
- do_compare (pixbuf,
- buffer_to_pixbuf (buffer, count, &err),
- err);
- }
- }
- else if (evt->keyval == 's') {
- /* save normally */
- if (pixbuf == NULL) {
- fprintf (stderr, "PIXBUF NULL\n");
- return;
- }
-
- if (!gdk_pixbuf_save (pixbuf, "foo.jpg", "jpeg",
- &err,
- "quality", "100",
- NULL)) {
- fprintf (stderr, "%s", err->message);
- g_error_free (err);
- } else {
- do_compare (pixbuf,
- gdk_pixbuf_new_from_file ("foo.jpg", &err),
- err);
- }
- }
-
- if (evt->keyval == 'p' && (evt->state & GDK_CONTROL_MASK)) {
- /* save to callback */
- if (pixbuf == NULL) {
- fprintf (stderr, "PIXBUF NULL\n");
- return;
- }
-
- loader = gdk_pixbuf_loader_new ();
- if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "png",
- &err,
- "tEXt::Software", "testpixbuf-save",
- NULL)
- || !gdk_pixbuf_loader_close (loader, &err)) {
- fprintf (stderr, "%s", err->message);
- g_error_free (err);
- } else {
- do_compare (pixbuf,
- g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
- err);
- g_object_unref (loader);
- }
- }
- else if (evt->keyval == 'P') {
- /* save to buffer */
- if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "png",
- &err,
- "tEXt::Software", "testpixbuf-save",
- NULL)) {
- fprintf (stderr, "%s", err->message);
- g_error_free (err);
- } else {
- do_compare (pixbuf,
- buffer_to_pixbuf (buffer, count, &err),
- err);
- }
- }
- else if (evt->keyval == 'p') {
- if (pixbuf == NULL) {
- fprintf (stderr, "PIXBUF NULL\n");
- return;
- }
-
- if (!gdk_pixbuf_save (pixbuf, "foo.png", "png",
- &err,
- "tEXt::Software", "testpixbuf-save",
- NULL)) {
- fprintf (stderr, "%s", err->message);
- g_error_free (err);
- } else {
- do_compare(pixbuf,
- gdk_pixbuf_new_from_file ("foo.png", &err),
- err);
- }
- }
-
- if (evt->keyval == 'i' && (evt->state & GDK_CONTROL_MASK)) {
- /* save to callback */
- if (pixbuf == NULL) {
- fprintf (stderr, "PIXBUF NULL\n");
- return;
- }
-
- loader = gdk_pixbuf_loader_new ();
- if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "ico",
- &err,
- NULL)
- || !gdk_pixbuf_loader_close (loader, &err)) {
- fprintf (stderr, "%s", err->message);
- g_error_free (err);
- } else {
- do_compare (pixbuf,
- g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
- err);
- g_object_unref (loader);
- }
- }
- else if (evt->keyval == 'I') {
- /* save to buffer */
- if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "ico",
- &err,
- NULL)) {
- fprintf (stderr, "%s", err->message);
- g_error_free (err);
- } else {
- do_compare (pixbuf,
- buffer_to_pixbuf (buffer, count, &err),
- err);
- }
- }
- else if (evt->keyval == 'i') {
- if (pixbuf == NULL) {
- fprintf (stderr, "PIXBUF NULL\n");
- return;
- }
-
- if (!gdk_pixbuf_save (pixbuf, "foo.ico", "ico",
- &err,
- NULL)) {
- fprintf (stderr, "%s", err->message);
- g_error_free (err);
- } else {
- do_compare(pixbuf,
- gdk_pixbuf_new_from_file ("foo.ico", &err),
- err);
- }
- }
-
- if (evt->keyval == 'a') {
- if (pixbuf == NULL) {
- fprintf (stderr, "PIXBUF NULL\n");
- return;
- } else {
- GdkPixbuf *alpha_buf;
-
- alpha_buf = gdk_pixbuf_add_alpha (pixbuf,
- FALSE, 0, 0, 0);
-
- g_object_set_data_full (G_OBJECT (da),
- "pixbuf", alpha_buf,
- (GDestroyNotify) g_object_unref);
- }
- }
-}
-
-
-static int
-close_app (GtkWidget *widget, gpointer data)
-{
- gtk_main_quit ();
- return TRUE;
-}
-
-static gboolean
-draw_cb (GtkWidget *drawing_area, cairo_t *cr, gpointer data)
-{
- GdkPixbuf *pixbuf;
-
- pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (drawing_area),
- "pixbuf");
-
- gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
- cairo_paint (cr);
-
- return FALSE;
-}
-
-static int
-configure_cb (GtkWidget *drawing_area, GdkEventConfigure *evt, gpointer data)
-{
- GdkPixbuf *pixbuf;
-
- pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (drawing_area),
- "pixbuf");
-
- g_print ("X:%d Y:%d\n", evt->width, evt->height);
- if (evt->width != gdk_pixbuf_get_width (pixbuf) || evt->height != gdk_pixbuf_get_height (pixbuf)) {
- GdkWindow *root;
- GdkPixbuf *new_pixbuf;
-
- root = gdk_get_default_root_window ();
- new_pixbuf = gdk_pixbuf_get_from_window (root,
- 0, 0, evt->width, evt->height);
- g_object_set_data_full (G_OBJECT (drawing_area), "pixbuf", new_pixbuf,
- (GDestroyNotify) g_object_unref);
- }
-
- return FALSE;
-}
-
-int
-main (int argc, char **argv)
-{
- GdkWindow *root;
- GtkWidget *window;
- GtkWidget *vbox;
- GtkWidget *drawing_area;
- GdkPixbuf *pixbuf;
-
- gtk_init (&argc, &argv);
-
- root = gdk_get_default_root_window ();
- pixbuf = gdk_pixbuf_get_from_window (root,
- 0, 0, 150, 160);
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- g_signal_connect (window, "delete_event",
- G_CALLBACK (close_app), NULL);
- g_signal_connect (window, "destroy",
- G_CALLBACK (close_app), NULL);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- drawing_area = gtk_drawing_area_new ();
- gtk_widget_set_size_request (GTK_WIDGET (drawing_area),
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf));
- g_signal_connect (drawing_area, "draw",
- G_CALLBACK (draw_cb), NULL);
-
- g_signal_connect (drawing_area, "configure_event",
- G_CALLBACK (configure_cb), NULL);
- g_signal_connect (window, "key_press_event",
- G_CALLBACK (keypress_check), drawing_area);
- g_object_set_data_full (G_OBJECT (drawing_area), "pixbuf", pixbuf,
- (GDestroyNotify) g_object_unref);
- gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
-
- gtk_widget_show_all (window);
- gtk_main ();
- return 0;
-}
+++ /dev/null
-#include "config.h"
-#include <gtk/gtk.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-GdkInterpType interp_type = GDK_INTERP_BILINEAR;
-int overall_alpha = 255;
-GdkPixbuf *pixbuf;
-GtkWidget *darea;
-
-void
-set_interp_type (GtkWidget *widget, gpointer data)
-{
- guint types[] = { GDK_INTERP_NEAREST,
- GDK_INTERP_BILINEAR,
- GDK_INTERP_TILES,
- GDK_INTERP_HYPER };
-
- interp_type = types[gtk_combo_box_get_active (GTK_COMBO_BOX (widget))];
- gtk_widget_queue_draw (darea);
-}
-
-void
-overall_changed_cb (GtkAdjustment *adjustment, gpointer data)
-{
- if (gtk_adjustment_get_value (adjustment) != overall_alpha)
- {
- overall_alpha = gtk_adjustment_get_value (adjustment);
- gtk_widget_queue_draw (darea);
- }
-}
-
-gboolean
-draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
-{
- GdkPixbuf *dest;
- int width, height;
-
- width = gtk_widget_get_allocated_width (widget);
- height = gtk_widget_get_allocated_height (widget);
-
- dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
-
- gdk_pixbuf_composite_color (pixbuf, dest,
- 0, 0, width, height,
- 0, 0,
- (double) width / gdk_pixbuf_get_width (pixbuf),
- (double) height / gdk_pixbuf_get_height (pixbuf),
- interp_type, overall_alpha,
- 0, 0, 16, 0xaaaaaa, 0x555555);
-
- gdk_cairo_set_source_pixbuf (cr, dest, 0, 0);
- cairo_paint (cr);
-
- g_object_unref (dest);
-
- return TRUE;
-}
-
-int
-main(int argc, char **argv)
-{
- GtkWidget *window, *vbox;
- GtkWidget *combo_box;
- GtkWidget *alignment;
- GtkWidget *hbox, *label, *hscale;
- GtkAdjustment *adjustment;
- GtkRequisition scratch_requisition;
- const gchar *creator;
- GError *error;
-
- gtk_init (&argc, &argv);
-
- if (argc != 2) {
- fprintf (stderr, "Usage: testpixbuf-scale FILE\n");
- exit (1);
- }
-
- error = NULL;
- pixbuf = gdk_pixbuf_new_from_file (argv[1], &error);
- if (!pixbuf) {
- fprintf (stderr, "Cannot load image: %s\n",
- error->message);
- g_error_free (error);
- exit(1);
- }
-
- creator = gdk_pixbuf_get_option (pixbuf, "tEXt::Software");
- if (creator)
- g_print ("%s was created by '%s'\n", argv[1], creator);
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- g_signal_connect (window, "destroy",
- G_CALLBACK (gtk_main_quit), NULL);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- combo_box = gtk_combo_box_text_new ();
-
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "NEAREST");
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "BILINEAR");
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "TILES");
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "HYPER");
-
- gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 1);
-
- g_signal_connect (combo_box, "changed",
- G_CALLBACK (set_interp_type),
- NULL);
-
- alignment = gtk_alignment_new (0.0, 0.0, 0.0, 0.5);
- gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
- label = gtk_label_new ("Overall Alpha:");
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
- adjustment = gtk_adjustment_new (overall_alpha, 0, 255, 1, 10, 0);
- g_signal_connect (adjustment, "value_changed",
- G_CALLBACK (overall_changed_cb), NULL);
-
- hscale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
- gtk_scale_set_digits (GTK_SCALE (hscale), 0);
- gtk_box_pack_start (GTK_BOX (hbox), hscale, TRUE, TRUE, 0);
-
- gtk_container_add (GTK_CONTAINER (alignment), combo_box);
- gtk_widget_show_all (vbox);
-
- /* Compute the size without the drawing area, so we know how big to make the default size */
- gtk_widget_get_preferred_size ( (vbox),
- &scratch_requisition, NULL);
-
- darea = gtk_drawing_area_new ();
- gtk_box_pack_start (GTK_BOX (vbox), darea, TRUE, TRUE, 0);
-
- g_signal_connect (darea, "draw",
- G_CALLBACK (draw_cb), NULL);
-
- gtk_window_set_default_size (GTK_WINDOW (window),
- gdk_pixbuf_get_width (pixbuf),
- scratch_requisition.height + gdk_pixbuf_get_height (pixbuf));
-
- gtk_widget_show_all (window);
-
- gtk_main ();
-
- return 0;
-}
testtreecolumns \
testtreecolumnsizing \
testtreesort \
- testverticalcells \
+ testverticalcells \
treestoretest \
testxinerama \
testwindows \
testnoscreen \
testtreepos \
testsensitive \
- testtextview
+ testtextview \
+ testanimation \
+ testpixbuf-save \
+ testpixbuf-color \
+ testpixbuf-scale
if USE_X11
noinst_PROGRAMS += testerrors
testtreepos_DEPENDENCIES = $(TEST_DEPS)
testsensitive_DEPENDENCIES = $(TEST_DEPS)
testtextview_DEPENDENCIES = $(TEST_DEPS)
+testanimation_DEPENDENCIES = $(TEST_DEPS)
+testpixbuf_save_DEPENDENCIES = $(TEST_DEPS)
+testpixbuf_color_DEPENDENCIES = $(TEST_DEPS)
+testpixbuf_scale_DEPENDENCIES = $(TEST_DEPS)
flicker_LDADD = $(LDADDS)
simple_LDADD = $(LDADDS)
testtreepos_LDADD = $(LDADDS)
testsensitive_LDADD = $(LDADDS)
testtextview_LDADD = $(LDADDS)
+testanimation_LDADD = $(LDADDS)
+testpixbuf_save_LDADD = $(LDADDS)
+testpixbuf_color_LDADD = $(LDADDS)
+testpixbuf_scale_LDADD = $(LDADDS)
testentrycompletion_SOURCES = \
testtextview_SOURCES = testtextview.c
+testanimation_SOURCES = testanimation.c
+
+testpixbuf_scale_SOURCES = testpixbuf-scale.c
+
+testpixbuf_color_SOURCES = testpixbuf-color.c
+
+testpixbuf_save_SOURCES = testpixbuf-save.c
+
EXTRA_DIST += \
gradient1.png \
--- /dev/null
+
+/* testpixbuf -- test program for gdk-pixbuf code
+ * Copyright (C) 1999 Mark Crichton, Larry Ewing
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <gtk/gtk.h>
+
+typedef struct _LoadContext LoadContext;
+
+struct _LoadContext
+{
+ gchar *filename;
+ GtkWidget *window;
+ GdkPixbufLoader *pixbuf_loader;
+ guint load_timeout;
+ FILE* image_stream;
+};
+
+static void
+destroy_context (gpointer data)
+{
+ LoadContext *lc = data;
+
+ g_free (lc->filename);
+
+ if (lc->load_timeout)
+ g_source_remove (lc->load_timeout);
+
+ if (lc->image_stream)
+ fclose (lc->image_stream);
+
+ if (lc->pixbuf_loader)
+ {
+ gdk_pixbuf_loader_close (lc->pixbuf_loader, NULL);
+ g_object_unref (lc->pixbuf_loader);
+ }
+
+ g_free (lc);
+}
+
+static LoadContext*
+get_load_context (GtkWidget *image)
+{
+ LoadContext *lc;
+
+ lc = g_object_get_data (G_OBJECT (image), "lc");
+
+ if (lc == NULL)
+ {
+ lc = g_new0 (LoadContext, 1);
+
+ g_object_set_data_full (G_OBJECT (image),
+ "lc",
+ lc,
+ destroy_context);
+ }
+
+ return lc;
+}
+
+static void
+progressive_prepared_callback (GdkPixbufLoader* loader,
+ gpointer data)
+{
+ GdkPixbuf* pixbuf;
+ GtkWidget* image;
+
+ image = GTK_WIDGET (data);
+
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+
+ /* Avoid displaying random memory contents, since the pixbuf
+ * isn't filled in yet.
+ */
+ gdk_pixbuf_fill (pixbuf, 0xaaaaaaff);
+
+ /* Could set the pixbuf instead, if we only wanted to display
+ * static images.
+ */
+ gtk_image_set_from_animation (GTK_IMAGE (image),
+ gdk_pixbuf_loader_get_animation (loader));
+}
+
+static void
+progressive_updated_callback (GdkPixbufLoader* loader,
+ gint x, gint y, gint width, gint height,
+ gpointer data)
+{
+ GtkWidget* image;
+
+ image = GTK_WIDGET (data);
+
+ /* We know the pixbuf inside the GtkImage has changed, but the image
+ * itself doesn't know this; so queue a redraw. If we wanted to be
+ * really efficient, we could use a drawing area or something
+ * instead of a GtkImage, so we could control the exact position of
+ * the pixbuf on the display, then we could queue a draw for only
+ * the updated area of the image.
+ */
+
+ /* We only really need to redraw if the image's animation iterator
+ * is gdk_pixbuf_animation_iter_on_currently_loading_frame(), but
+ * who cares.
+ */
+
+ gtk_widget_queue_draw (image);
+}
+
+static gint
+progressive_timeout (gpointer data)
+{
+ GtkWidget *image;
+ LoadContext *lc;
+
+ image = GTK_WIDGET (data);
+ lc = get_load_context (image);
+
+ /* This shows off fully-paranoid error handling, so looks scary.
+ * You could factor out the error handling code into a nice separate
+ * function to make things nicer.
+ */
+
+ if (lc->image_stream)
+ {
+ size_t bytes_read;
+ guchar buf[256];
+ GError *error = NULL;
+
+ bytes_read = fread (buf, 1, 256, lc->image_stream);
+
+ if (ferror (lc->image_stream))
+ {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Failure reading image file 'alphatest.png': %s",
+ g_strerror (errno));
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+
+ fclose (lc->image_stream);
+ lc->image_stream = NULL;
+
+ gtk_widget_show (dialog);
+
+ lc->load_timeout = 0;
+
+ return FALSE; /* uninstall the timeout */
+ }
+
+ if (!gdk_pixbuf_loader_write (lc->pixbuf_loader,
+ buf, bytes_read,
+ &error))
+ {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Failed to load image: %s",
+ error->message);
+
+ g_error_free (error);
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+
+ fclose (lc->image_stream);
+ lc->image_stream = NULL;
+
+ gtk_widget_show (dialog);
+
+ lc->load_timeout = 0;
+
+ return FALSE; /* uninstall the timeout */
+ }
+
+ if (feof (lc->image_stream))
+ {
+ fclose (lc->image_stream);
+ lc->image_stream = NULL;
+
+ /* Errors can happen on close, e.g. if the image
+ * file was truncated we'll know on close that
+ * it was incomplete.
+ */
+ error = NULL;
+ if (!gdk_pixbuf_loader_close (lc->pixbuf_loader,
+ &error))
+ {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Failed to load image: %s",
+ error->message);
+
+ g_error_free (error);
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+
+ gtk_widget_show (dialog);
+
+ g_object_unref (lc->pixbuf_loader);
+ lc->pixbuf_loader = NULL;
+
+ lc->load_timeout = 0;
+
+ return FALSE; /* uninstall the timeout */
+ }
+
+ g_object_unref (lc->pixbuf_loader);
+ lc->pixbuf_loader = NULL;
+ }
+ }
+ else
+ {
+ lc->image_stream = fopen (lc->filename, "r");
+
+ if (lc->image_stream == NULL)
+ {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Unable to open image file '%s': %s",
+ lc->filename,
+ g_strerror (errno));
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+
+ gtk_widget_show (dialog);
+
+ lc->load_timeout = 0;
+
+ return FALSE; /* uninstall the timeout */
+ }
+
+ if (lc->pixbuf_loader)
+ {
+ gdk_pixbuf_loader_close (lc->pixbuf_loader, NULL);
+ g_object_unref (lc->pixbuf_loader);
+ lc->pixbuf_loader = NULL;
+ }
+
+ lc->pixbuf_loader = gdk_pixbuf_loader_new ();
+
+ g_signal_connect (lc->pixbuf_loader, "area_prepared",
+ G_CALLBACK (progressive_prepared_callback), image);
+ g_signal_connect (lc->pixbuf_loader, "area_updated",
+ G_CALLBACK (progressive_updated_callback), image);
+ }
+
+ /* leave timeout installed */
+ return TRUE;
+}
+
+static void
+start_progressive_loading (GtkWidget *image)
+{
+ LoadContext *lc;
+
+ lc = get_load_context (image);
+
+ /* This is obviously totally contrived (we slow down loading
+ * on purpose to show how incremental loading works).
+ * The real purpose of incremental loading is the case where
+ * you are reading data from a slow source such as the network.
+ * The timeout simply simulates a slow data source by inserting
+ * pauses in the reading process.
+ */
+ lc->load_timeout = gdk_threads_add_timeout (100,
+ progressive_timeout,
+ image);
+}
+
+static GtkWidget *
+do_image (const char *filename)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+ GtkWidget *image;
+ GtkWidget *label;
+ GtkWidget *align;
+ GtkWidget *window;
+ gchar *str, *escaped;
+ LoadContext *lc;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (window), "Image Loading");
+
+ gtk_container_set_border_width (GTK_CONTAINER (window), 8);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ label = gtk_label_new (NULL);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ escaped = g_markup_escape_text (filename, -1);
+ str = g_strdup_printf ("Progressively loading: <b>%s</b>", escaped);
+ gtk_label_set_markup (GTK_LABEL (label),
+ str);
+ g_free (escaped);
+ g_free (str);
+
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+ /* The alignment keeps the frame from growing when users resize
+ * the window
+ */
+ align = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (align), frame);
+ gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
+
+ image = gtk_image_new_from_pixbuf (NULL);
+ gtk_container_add (GTK_CONTAINER (frame), image);
+
+ lc = get_load_context (image);
+
+ lc->window = window;
+ lc->filename = g_strdup (filename);
+
+ start_progressive_loading (image);
+
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ g_signal_connect (window, "delete_event",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ gtk_widget_show_all (window);
+
+ return window;
+}
+
+static void
+do_nonprogressive (const gchar *filename)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+ GtkWidget *image;
+ GtkWidget *label;
+ GtkWidget *align;
+ GtkWidget *window;
+ gchar *str, *escaped;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (window), "Animation");
+
+ gtk_container_set_border_width (GTK_CONTAINER (window), 8);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ label = gtk_label_new (NULL);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ escaped = g_markup_escape_text (filename, -1);
+ str = g_strdup_printf ("Loaded from file: <b>%s</b>", escaped);
+ gtk_label_set_markup (GTK_LABEL (label),
+ str);
+ g_free (escaped);
+ g_free (str);
+
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+ /* The alignment keeps the frame from growing when users resize
+ * the window
+ */
+ align = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (align), frame);
+ gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
+
+ image = gtk_image_new_from_file (filename);
+ gtk_container_add (GTK_CONTAINER (frame), image);
+
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ g_signal_connect (window, "delete_event",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ gtk_widget_show_all (window);
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ gint i;
+
+ gtk_init (&argc, &argv);
+
+ i = 1;
+ while (i < argc)
+ {
+ do_image (argv[i]);
+ do_nonprogressive (argv[i]);
+
+ ++i;
+ }
+
+ gtk_main ();
+
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#define ICC_PROFILE "/usr/share/color/icc/bluish.icc"
+#define ICC_PROFILE_SIZE 3966
+
+static gboolean
+save_image_png (const gchar *filename, GdkPixbuf *pixbuf, GError **error)
+{
+ gchar *contents = NULL;
+ gchar *contents_encode = NULL;
+ gsize length;
+ gboolean ret;
+ gint len;
+
+ /* get icc file */
+ ret = g_file_get_contents (ICC_PROFILE, &contents, &length, error);
+ if (!ret)
+ goto out;
+ contents_encode = g_base64_encode ((const guchar *) contents, length);
+ ret = gdk_pixbuf_save (pixbuf, filename, "png", error,
+ "tEXt::Software", "Hello my name is dave",
+ "icc-profile", contents_encode,
+ NULL);
+ len = strlen (contents_encode);
+ g_debug ("ICC profile was %i bytes", len);
+out:
+ g_free (contents);
+ g_free (contents_encode);
+ return ret;
+}
+
+static gboolean
+save_image_tiff (const gchar *filename, GdkPixbuf *pixbuf, GError **error)
+{
+ gchar *contents = NULL;
+ gchar *contents_encode = NULL;
+ gsize length;
+ gboolean ret;
+ gint len;
+
+ /* get icc file */
+ ret = g_file_get_contents (ICC_PROFILE, &contents, &length, error);
+ if (!ret)
+ goto out;
+ contents_encode = g_base64_encode ((const guchar *) contents, length);
+ ret = gdk_pixbuf_save (pixbuf, filename, "tiff", error,
+ "icc-profile", contents_encode,
+ NULL);
+ len = strlen (contents_encode);
+ g_debug ("ICC profile was %i bytes", len);
+out:
+ g_free (contents);
+ g_free (contents_encode);
+ return ret;
+}
+
+static gboolean
+save_image_verify (const gchar *filename, GError **error)
+{
+ gboolean ret = FALSE;
+ GdkPixbuf *pixbuf = NULL;
+ const gchar *option;
+ gchar *icc_profile = NULL;
+ gsize len = 0;
+
+ /* load */
+ pixbuf = gdk_pixbuf_new_from_file (filename, error);
+ if (pixbuf == NULL)
+ goto out;
+
+ /* check values */
+ option = gdk_pixbuf_get_option (pixbuf, "icc-profile");
+ if (option == NULL) {
+ *error = g_error_new (1, 0, "no profile set");
+ goto out;
+ }
+
+ /* decode base64 */
+ icc_profile = (gchar *) g_base64_decode (option, &len);
+ if (len != ICC_PROFILE_SIZE) {
+ *error = g_error_new (1, 0,
+ "profile length invalid, got %" G_GSIZE_FORMAT,
+ len);
+ g_file_set_contents ("error.icc", icc_profile, len, NULL);
+ goto out;
+ }
+
+ /* success */
+ ret = TRUE;
+out:
+ if (pixbuf != NULL)
+ g_object_unref (pixbuf);
+ g_free (icc_profile);
+ return ret;
+}
+
+int
+main (int argc, char **argv)
+{
+ GdkWindow *root;
+ GdkPixbuf *pixbuf;
+ gboolean ret;
+ gint retval = 1;
+ GError *error = NULL;
+
+ gtk_init (&argc, &argv);
+
+ root = gdk_get_default_root_window ();
+ pixbuf = gdk_pixbuf_get_from_window (root,
+ 0, 0, 150, 160);
+
+ /* PASS */
+ g_debug ("try to save PNG with a profile");
+ ret = save_image_png ("icc-profile.png", pixbuf, &error);
+ if (!ret) {
+ g_warning ("FAILED: did not save image: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* PASS */
+ g_debug ("try to save TIFF with a profile");
+ ret = save_image_tiff ("icc-profile.tiff", pixbuf, &error);
+ if (!ret) {
+ g_warning ("FAILED: did not save image: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* PASS */
+ g_debug ("try to load PNG and get color attributes");
+ ret = save_image_verify ("icc-profile.png", &error);
+ if (!ret) {
+ g_warning ("FAILED: did not load image: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* PASS */
+ g_debug ("try to load TIFF and get color attributes");
+ ret = save_image_verify ("icc-profile.tiff", &error);
+ if (!ret) {
+ g_warning ("FAILED: did not load image: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* success */
+ retval = 0;
+ g_debug ("ALL OKAY!");
+out:
+ return retval;
+}
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+
+#include "config.h"
+#include <stdio.h>
+
+#include <gtk/gtk.h>
+
+static void
+compare_pixbufs (GdkPixbuf *pixbuf, GdkPixbuf *compare, const gchar *file_type)
+{
+ if ((gdk_pixbuf_get_width (pixbuf) !=
+ gdk_pixbuf_get_width (compare)) ||
+ (gdk_pixbuf_get_height (pixbuf) !=
+ gdk_pixbuf_get_height (compare)) ||
+ (gdk_pixbuf_get_n_channels (pixbuf) !=
+ gdk_pixbuf_get_n_channels (compare)) ||
+ (gdk_pixbuf_get_has_alpha (pixbuf) !=
+ gdk_pixbuf_get_has_alpha (compare)) ||
+ (gdk_pixbuf_get_bits_per_sample (pixbuf) !=
+ gdk_pixbuf_get_bits_per_sample (compare))) {
+ fprintf (stderr,
+ "saved %s file differs from copy in memory\n",
+ file_type);
+ } else {
+ guchar *orig_pixels;
+ guchar *compare_pixels;
+ gint orig_rowstride;
+ gint compare_rowstride;
+ gint width;
+ gint height;
+ gint bytes_per_pixel;
+ gint x, y;
+ guchar *p1, *p2;
+ gint count = 0;
+
+ orig_pixels = gdk_pixbuf_get_pixels (pixbuf);
+ compare_pixels = gdk_pixbuf_get_pixels (compare);
+
+ orig_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ compare_rowstride = gdk_pixbuf_get_rowstride (compare);
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+
+ /* well... */
+ bytes_per_pixel = gdk_pixbuf_get_n_channels (pixbuf);
+
+ p1 = orig_pixels;
+ p2 = compare_pixels;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width * bytes_per_pixel; x++)
+ count += (*p1++ != *p2++);
+
+ orig_pixels += orig_rowstride;
+ compare_pixels += compare_rowstride;
+
+ p1 = orig_pixels;
+ p2 = compare_pixels;
+ }
+
+ if (count > 0) {
+ fprintf (stderr,
+ "saved %s file differs from copy in memory\n",
+ file_type);
+ }
+ }
+}
+
+static gboolean
+save_to_loader (const gchar *buf, gsize count, GError **err, gpointer data)
+{
+ GdkPixbufLoader *loader = data;
+
+ return gdk_pixbuf_loader_write (loader, (const guchar *)buf, count, err);
+}
+
+static GdkPixbuf *
+buffer_to_pixbuf (const gchar *buf, gsize count, GError **err)
+{
+ GdkPixbufLoader *loader;
+ GdkPixbuf *pixbuf;
+
+ loader = gdk_pixbuf_loader_new ();
+ if (gdk_pixbuf_loader_write (loader, (const guchar *)buf, count, err) &&
+ gdk_pixbuf_loader_close (loader, err)) {
+ pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
+ g_object_unref (loader);
+ return pixbuf;
+ } else {
+ return NULL;
+ }
+}
+
+static void
+do_compare (GdkPixbuf *pixbuf, GdkPixbuf *compare, GError *err)
+{
+ if (compare == NULL) {
+ fprintf (stderr, "%s", err->message);
+ g_error_free (err);
+ } else {
+ compare_pixbufs (pixbuf, compare, "jpeg");
+ g_object_unref (compare);
+ }
+}
+
+static void
+keypress_check (GtkWidget *widget, GdkEventKey *evt, gpointer data)
+{
+ GdkPixbuf *pixbuf;
+ GtkDrawingArea *da = (GtkDrawingArea*)data;
+ GError *err = NULL;
+ gchar *buffer;
+ gsize count;
+ GdkPixbufLoader *loader;
+
+ pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (da), "pixbuf");
+
+ if (evt->keyval == 'q')
+ gtk_main_quit ();
+
+ if (evt->keyval == 's' && (evt->state & GDK_CONTROL_MASK)) {
+ /* save to callback */
+ if (pixbuf == NULL) {
+ fprintf (stderr, "PIXBUF NULL\n");
+ return;
+ }
+
+ loader = gdk_pixbuf_loader_new ();
+ if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "jpeg",
+ &err,
+ "quality", "100",
+ NULL) ||
+ !gdk_pixbuf_loader_close (loader, &err)) {
+ fprintf (stderr, "%s", err->message);
+ g_error_free (err);
+ } else {
+ do_compare (pixbuf,
+ g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
+ err);
+ g_object_unref (loader);
+ }
+ }
+ else if (evt->keyval == 'S') {
+ /* save to buffer */
+ if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "jpeg",
+ &err,
+ "quality", "100",
+ NULL)) {
+ fprintf (stderr, "%s", err->message);
+ g_error_free (err);
+ } else {
+ do_compare (pixbuf,
+ buffer_to_pixbuf (buffer, count, &err),
+ err);
+ }
+ }
+ else if (evt->keyval == 's') {
+ /* save normally */
+ if (pixbuf == NULL) {
+ fprintf (stderr, "PIXBUF NULL\n");
+ return;
+ }
+
+ if (!gdk_pixbuf_save (pixbuf, "foo.jpg", "jpeg",
+ &err,
+ "quality", "100",
+ NULL)) {
+ fprintf (stderr, "%s", err->message);
+ g_error_free (err);
+ } else {
+ do_compare (pixbuf,
+ gdk_pixbuf_new_from_file ("foo.jpg", &err),
+ err);
+ }
+ }
+
+ if (evt->keyval == 'p' && (evt->state & GDK_CONTROL_MASK)) {
+ /* save to callback */
+ if (pixbuf == NULL) {
+ fprintf (stderr, "PIXBUF NULL\n");
+ return;
+ }
+
+ loader = gdk_pixbuf_loader_new ();
+ if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "png",
+ &err,
+ "tEXt::Software", "testpixbuf-save",
+ NULL)
+ || !gdk_pixbuf_loader_close (loader, &err)) {
+ fprintf (stderr, "%s", err->message);
+ g_error_free (err);
+ } else {
+ do_compare (pixbuf,
+ g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
+ err);
+ g_object_unref (loader);
+ }
+ }
+ else if (evt->keyval == 'P') {
+ /* save to buffer */
+ if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "png",
+ &err,
+ "tEXt::Software", "testpixbuf-save",
+ NULL)) {
+ fprintf (stderr, "%s", err->message);
+ g_error_free (err);
+ } else {
+ do_compare (pixbuf,
+ buffer_to_pixbuf (buffer, count, &err),
+ err);
+ }
+ }
+ else if (evt->keyval == 'p') {
+ if (pixbuf == NULL) {
+ fprintf (stderr, "PIXBUF NULL\n");
+ return;
+ }
+
+ if (!gdk_pixbuf_save (pixbuf, "foo.png", "png",
+ &err,
+ "tEXt::Software", "testpixbuf-save",
+ NULL)) {
+ fprintf (stderr, "%s", err->message);
+ g_error_free (err);
+ } else {
+ do_compare(pixbuf,
+ gdk_pixbuf_new_from_file ("foo.png", &err),
+ err);
+ }
+ }
+
+ if (evt->keyval == 'i' && (evt->state & GDK_CONTROL_MASK)) {
+ /* save to callback */
+ if (pixbuf == NULL) {
+ fprintf (stderr, "PIXBUF NULL\n");
+ return;
+ }
+
+ loader = gdk_pixbuf_loader_new ();
+ if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "ico",
+ &err,
+ NULL)
+ || !gdk_pixbuf_loader_close (loader, &err)) {
+ fprintf (stderr, "%s", err->message);
+ g_error_free (err);
+ } else {
+ do_compare (pixbuf,
+ g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
+ err);
+ g_object_unref (loader);
+ }
+ }
+ else if (evt->keyval == 'I') {
+ /* save to buffer */
+ if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "ico",
+ &err,
+ NULL)) {
+ fprintf (stderr, "%s", err->message);
+ g_error_free (err);
+ } else {
+ do_compare (pixbuf,
+ buffer_to_pixbuf (buffer, count, &err),
+ err);
+ }
+ }
+ else if (evt->keyval == 'i') {
+ if (pixbuf == NULL) {
+ fprintf (stderr, "PIXBUF NULL\n");
+ return;
+ }
+
+ if (!gdk_pixbuf_save (pixbuf, "foo.ico", "ico",
+ &err,
+ NULL)) {
+ fprintf (stderr, "%s", err->message);
+ g_error_free (err);
+ } else {
+ do_compare(pixbuf,
+ gdk_pixbuf_new_from_file ("foo.ico", &err),
+ err);
+ }
+ }
+
+ if (evt->keyval == 'a') {
+ if (pixbuf == NULL) {
+ fprintf (stderr, "PIXBUF NULL\n");
+ return;
+ } else {
+ GdkPixbuf *alpha_buf;
+
+ alpha_buf = gdk_pixbuf_add_alpha (pixbuf,
+ FALSE, 0, 0, 0);
+
+ g_object_set_data_full (G_OBJECT (da),
+ "pixbuf", alpha_buf,
+ (GDestroyNotify) g_object_unref);
+ }
+ }
+}
+
+
+static int
+close_app (GtkWidget *widget, gpointer data)
+{
+ gtk_main_quit ();
+ return TRUE;
+}
+
+static gboolean
+draw_cb (GtkWidget *drawing_area, cairo_t *cr, gpointer data)
+{
+ GdkPixbuf *pixbuf;
+
+ pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (drawing_area),
+ "pixbuf");
+
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ cairo_paint (cr);
+
+ return FALSE;
+}
+
+static int
+configure_cb (GtkWidget *drawing_area, GdkEventConfigure *evt, gpointer data)
+{
+ GdkPixbuf *pixbuf;
+
+ pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (drawing_area),
+ "pixbuf");
+
+ g_print ("X:%d Y:%d\n", evt->width, evt->height);
+ if (evt->width != gdk_pixbuf_get_width (pixbuf) || evt->height != gdk_pixbuf_get_height (pixbuf)) {
+ GdkWindow *root;
+ GdkPixbuf *new_pixbuf;
+
+ root = gdk_get_default_root_window ();
+ new_pixbuf = gdk_pixbuf_get_from_window (root,
+ 0, 0, evt->width, evt->height);
+ g_object_set_data_full (G_OBJECT (drawing_area), "pixbuf", new_pixbuf,
+ (GDestroyNotify) g_object_unref);
+ }
+
+ return FALSE;
+}
+
+int
+main (int argc, char **argv)
+{
+ GdkWindow *root;
+ GtkWidget *window;
+ GtkWidget *vbox;
+ GtkWidget *drawing_area;
+ GdkPixbuf *pixbuf;
+
+ gtk_init (&argc, &argv);
+
+ root = gdk_get_default_root_window ();
+ pixbuf = gdk_pixbuf_get_from_window (root,
+ 0, 0, 150, 160);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (window, "delete_event",
+ G_CALLBACK (close_app), NULL);
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (close_app), NULL);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ drawing_area = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (GTK_WIDGET (drawing_area),
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
+ g_signal_connect (drawing_area, "draw",
+ G_CALLBACK (draw_cb), NULL);
+
+ g_signal_connect (drawing_area, "configure_event",
+ G_CALLBACK (configure_cb), NULL);
+ g_signal_connect (window, "key_press_event",
+ G_CALLBACK (keypress_check), drawing_area);
+ g_object_set_data_full (G_OBJECT (drawing_area), "pixbuf", pixbuf,
+ (GDestroyNotify) g_object_unref);
+ gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
+
+ gtk_widget_show_all (window);
+ gtk_main ();
+ return 0;
+}
--- /dev/null
+#include "config.h"
+#include <gtk/gtk.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+GdkInterpType interp_type = GDK_INTERP_BILINEAR;
+int overall_alpha = 255;
+GdkPixbuf *pixbuf;
+GtkWidget *darea;
+
+void
+set_interp_type (GtkWidget *widget, gpointer data)
+{
+ guint types[] = { GDK_INTERP_NEAREST,
+ GDK_INTERP_BILINEAR,
+ GDK_INTERP_TILES,
+ GDK_INTERP_HYPER };
+
+ interp_type = types[gtk_combo_box_get_active (GTK_COMBO_BOX (widget))];
+ gtk_widget_queue_draw (darea);
+}
+
+void
+overall_changed_cb (GtkAdjustment *adjustment, gpointer data)
+{
+ if (gtk_adjustment_get_value (adjustment) != overall_alpha)
+ {
+ overall_alpha = gtk_adjustment_get_value (adjustment);
+ gtk_widget_queue_draw (darea);
+ }
+}
+
+gboolean
+draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+ GdkPixbuf *dest;
+ int width, height;
+
+ width = gtk_widget_get_allocated_width (widget);
+ height = gtk_widget_get_allocated_height (widget);
+
+ dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
+
+ gdk_pixbuf_composite_color (pixbuf, dest,
+ 0, 0, width, height,
+ 0, 0,
+ (double) width / gdk_pixbuf_get_width (pixbuf),
+ (double) height / gdk_pixbuf_get_height (pixbuf),
+ interp_type, overall_alpha,
+ 0, 0, 16, 0xaaaaaa, 0x555555);
+
+ gdk_cairo_set_source_pixbuf (cr, dest, 0, 0);
+ cairo_paint (cr);
+
+ g_object_unref (dest);
+
+ return TRUE;
+}
+
+int
+main(int argc, char **argv)
+{
+ GtkWidget *window, *vbox;
+ GtkWidget *combo_box;
+ GtkWidget *alignment;
+ GtkWidget *hbox, *label, *hscale;
+ GtkAdjustment *adjustment;
+ GtkRequisition scratch_requisition;
+ const gchar *creator;
+ GError *error;
+
+ gtk_init (&argc, &argv);
+
+ if (argc != 2) {
+ fprintf (stderr, "Usage: testpixbuf-scale FILE\n");
+ exit (1);
+ }
+
+ error = NULL;
+ pixbuf = gdk_pixbuf_new_from_file (argv[1], &error);
+ if (!pixbuf) {
+ fprintf (stderr, "Cannot load image: %s\n",
+ error->message);
+ g_error_free (error);
+ exit(1);
+ }
+
+ creator = gdk_pixbuf_get_option (pixbuf, "tEXt::Software");
+ if (creator)
+ g_print ("%s was created by '%s'\n", argv[1], creator);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ combo_box = gtk_combo_box_text_new ();
+
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "NEAREST");
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "BILINEAR");
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "TILES");
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "HYPER");
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 1);
+
+ g_signal_connect (combo_box, "changed",
+ G_CALLBACK (set_interp_type),
+ NULL);
+
+ alignment = gtk_alignment_new (0.0, 0.0, 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+ label = gtk_label_new ("Overall Alpha:");
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ adjustment = gtk_adjustment_new (overall_alpha, 0, 255, 1, 10, 0);
+ g_signal_connect (adjustment, "value_changed",
+ G_CALLBACK (overall_changed_cb), NULL);
+
+ hscale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
+ gtk_scale_set_digits (GTK_SCALE (hscale), 0);
+ gtk_box_pack_start (GTK_BOX (hbox), hscale, TRUE, TRUE, 0);
+
+ gtk_container_add (GTK_CONTAINER (alignment), combo_box);
+ gtk_widget_show_all (vbox);
+
+ /* Compute the size without the drawing area, so we know how big to make the default size */
+ gtk_widget_get_preferred_size ( (vbox),
+ &scratch_requisition, NULL);
+
+ darea = gtk_drawing_area_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), darea, TRUE, TRUE, 0);
+
+ g_signal_connect (darea, "draw",
+ G_CALLBACK (draw_cb), NULL);
+
+ gtk_window_set_default_size (GTK_WINDOW (window),
+ gdk_pixbuf_get_width (pixbuf),
+ scratch_requisition.height + gdk_pixbuf_get_height (pixbuf));
+
+ gtk_widget_show_all (window);
+
+ gtk_main ();
+
+ return 0;
+}